package com.xb.cloud.gateway.handler;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.xb.cloud.gateway.client.ClientInfo;
import com.xb.cloud.gateway.client.Context;
import com.xb.cloud.gateway.client.RtnCodes;
import com.xb.cloud.gateway.client.RtnInfo;
import com.xb.cloud.gateway.domain.LoggerVO;
import com.xb.cloud.gateway.utils.WebUtil;

@Component
public class LogHandler implements Handler {
	private static Logger logger = LoggerFactory.getLogger(LogHandler.class);

	public void execute(Context wlc)  {
		String urlPath = wlc.getUrlPath();
		String urlMethod = urlPath;
		
		//5个时间点信息
		long appCallTimeMs;
		try {
			appCallTimeMs = Long.valueOf(wlc.getRequestInfo().getBizPara().get("timestamp"))*1000;
		} catch (NumberFormatException e1) {
			appCallTimeMs = System.currentTimeMillis();
		}
		long serverStartTimeMs = wlc.getTimeLine().getRequestTime();
		long adapterStartTimeMs = wlc.getTimeLine().getServiceRequestTime();
		long adapterEndTimeMs = wlc.getTimeLine().getServiceResponseTime();
		long serverEndTimeMs = System.currentTimeMillis();
		
		//log 记录入参
		Map<String, String> bizParaForLog = wlc.getRequestInfo().getBizPara();
		bizParaForLog.put("provinceId", wlc.getRequestInfo().getProvinceId());
		bizParaForLog.put("userToken", wlc.getRequestInfo().getUserToken());
		String bizParaForLogJson = JSON.toJSONString(bizParaForLog);
		
		
		LoggerVO vo = new LoggerVO();
		vo.setUrlPathMethod(urlMethod);
		vo.setServerIp(WebUtil.getLocalIp());
		
		ClientInfo clientInfo = wlc.getRequestInfo().getClientInfo();
		if(clientInfo != null){
			if(clientInfo.getNetType() == null || "".equals(clientInfo.getNetType().trim())){//处理日志无该字段数据
				vo.setNetType("none");
			}else{
				vo.setNetType(clientInfo.getNetType());
			}
			
			try {
				vo.setIaddr(Integer.valueOf(clientInfo.getIaddr()));
			} catch (NumberFormatException e) {
				vo.setIaddr(-1);
			}
			
			try {
				vo.setProvinceId(Integer.valueOf( wlc.getRequestInfo().getProvinceId()));
			} catch (NumberFormatException e) {
				vo.setProvinceId(-1);
			}
			
			vo.setClientAppVersion(clientInfo.getClientAppVersion());
			vo.setClientSystem(clientInfo.getClientSystem());
			vo.setClientVersion(clientInfo.getClientVersion());
			vo.setDeviceCode(clientInfo.getDeviceCode());
			vo.setLatitude(clientInfo.getLatitude());
			vo.setLongitude(clientInfo.getLongitude());
			vo.setTraderName(clientInfo.getTraderName());
			vo.setUnionKey(clientInfo.getUnionKey());
			vo.setClientIp(wlc.getRequestIp());
			vo.setPhoneType(clientInfo.getPhoneType());
			vo.setImei(clientInfo.getImei());
			vo.setIdfa(clientInfo.getIdfa());
			vo.setDeviceToken(clientInfo.getDeviceToken());
			vo.setIsRoot(clientInfo.getIsRoot());
			
		}
		
		//入参
		vo.setParas(bizParaForLogJson);
		
		//userId
		vo.setUserId(wlc.getCurrentUserId());
		
		//adapter返回数据
		vo.setData(JSON.toJSONString(wlc.getRtnInfo()));
		
		//5个时间点
		vo.setAppCallTime(appCallTimeMs);
		vo.setServerStartTime(serverStartTimeMs);
		vo.setServerEndTime(serverEndTimeMs);
		vo.setAdapterStartTime(adapterStartTimeMs);
		vo.setAdapterEndTime(adapterEndTimeMs);
		
		//3个耗时
		vo.setAppToServerCost(covertLongToInt(serverStartTimeMs - appCallTimeMs));
		vo.setServerCost(covertLongToInt(serverEndTimeMs - serverStartTimeMs));
		int adapterCost = covertLongToInt(adapterEndTimeMs - adapterStartTimeMs);
		vo.setAdapterCost(adapterCost);
		
		//0-正常 1-adapter超时 2-adpter异常 3-adpater正常错误4-venus异常5-adpater被降级6-安全验证不通过
		RtnInfo re = wlc.getRtnInfo();
		String rtn_code = re.getRtnCode();
		vo.setErrorCode(rtn_code);
		if("00000000".equals(rtn_code)){
			vo.setErrorType(0);
			vo.setLevel("info");
		}else if(RtnCodes.ADAPTER_TIMEOUT.equals(rtn_code)){//adapter超时：000000000006
			vo.setErrorType(1);
			vo.setLevel("error");
		}else if(RtnCodes.ADAPTER_EXCEPTION.equals(rtn_code)){//adapter异常：000000000007
			vo.setErrorType(2);
			vo.setLevel("error");
		}else if(isVenusException(rtn_code)){//系统错误码“000000000008-10”
			vo.setErrorType(4);
			vo.setLevel("error");
		}else if(RtnCodes.SERVICE_REFEREE_IGNORE.equals(rtn_code)){//"000000000012"服务因降级而被忽略
			vo.setErrorType(5);
			vo.setLevel("error");
		}else if("000000000001".equals(rtn_code)){//安全验证，安全参数错误(some param empty) "000000000001" adapter业务参数错误也使用该码
			vo.setErrorType(6);
			vo.setLevel("error");
		}else if("000000000003".equals(rtn_code) || 
				RtnCodes.BLACK_DECICECODE_LIST.equals(rtn_code)){//安全验证签名错误"000000000003"
			vo.setErrorType(7);
			vo.setLevel("error");
		}else if("000000000004".equals(rtn_code)){//安全验证时间非法 "000000000004"
			vo.setErrorType(8);
			vo.setLevel("error");
		}else{
			if(vo.getErrorCode() == null){//脏日志特殊标记
				vo.setErrorCode("-110");
			}
			vo.setErrorType(3);
			vo.setLevel("error");
		}
		
		String logJosn = JSON.toJSONString(vo);
		logger.info(logJosn);
	}
	
	private int covertLongToInt(long l){
		int i = -1;
		try {
			i = Integer.valueOf(String.valueOf(l));
		} catch (NumberFormatException e) {
			//主要是防止脏timestamp导致异常，引起系统outbaind异常。强制将脏时间差置为-1
			i = -1;
		}
		return i;
	}
	
	private boolean isVenusException(String rtn_code){
		return RtnCodes.CONTEXT_BUILD_ERROR.equals(rtn_code) || RtnCodes.INBOUND_EXCEPTION.equals(rtn_code);
	}

	
	

}
